#include "Histogram.h"

Histogram::Histogram(void)
{
}


Histogram::~Histogram(void)
{
}

void Histogram::hist(Mat& input,Mat& output,int hist_size)
{
	vector<Mat>canali;
	split(input,canali);
	
	int histSize[]={hist_size};//numero di bin	
	int dimensioni = 1;
	float range_dim1[]={0, 255.0};
	const float* range[]={range_dim1};
	
	
	for(int c = 0;c<input.channels();c++)
	{

		int canale[] = {0};
		MatND histImg;
		calcHist(&canali[c],1,canale,Mat(),histImg,dimensioni,histSize,range,true,false);		
		
		histImg=plotHist(histImg,histSize[0]);
		
		stringstream ss;
		ss<<"hist ["<<c<<"]"<<endl;
		imshow(ss.str(),histImg);

		waitKey(5);	
	 
	}
}

Mat Histogram::plotHist(MatND& hist,int histSize)
{
	Mat histImg(histSize,histSize,CV_8U,cv::Scalar(255));

	double maxVal=0;
    double minVal=0;
    cv::minMaxLoc(hist, &minVal, &maxVal, 0, 0);

	// set highest point at 90% of nbins
    int hpt = static_cast<int>(0.9*histSize);

	for(int i = 0 ; i<histSize; i++)
	{

		 float binVal = hist.at<float>(i);
         int intensity = static_cast<int>(binVal*hpt/maxVal);

		cout<<hist.at<float>(i)<<endl;
		cv::line(histImg,Point(i,histSize), Point(i,histSize-intensity),Scalar::all(0)); 
	}
	imshow("pr2",histImg);
	return histImg;
}

//-------------------------------------------------------------------------------
//@test
void Histogram::getHistogram(Mat& img)
{
	cv::MatND outputhist;

	int nimages = 1;
	int canale_usato[]= {0};

	Mat mask=Mat(); //no mask

	int dimensioni = 1;
	int histSize[]={20};//numero di bin	

	float range_dim1[]={0, 255.0};
	const float* range[]={range_dim1};

	 
	//calcolo l'istogramma
	
	cv:calcHist(&img,nimages,canale_usato,mask,outputhist,dimensioni,histSize,range,true,false);
	cout<<"ok"<<endl;

	Mat histImg(histSize[0],histSize[0],CV_8U,cv::Scalar(255));

	double maxVal=0;
    double minVal=0;
    cv::minMaxLoc(outputhist, &minVal, &maxVal, 0, 0);

	// set highest point at 90% of nbins
    int hpt = static_cast<int>(0.9*histSize[0]);

	for(int i = 0 ; i<histSize[0]; i++)
	{

		 float binVal = outputhist.at<float>(i);
         int intensity = static_cast<int>(binVal*hpt/maxVal);

		cout<<outputhist.at<float>(i)<<endl;
		cv::line(histImg,Point(i,histSize[0]), Point(i,histSize[0]-intensity),Scalar::all(0)); 
	//	for(int j = 0;j<outputhist.at<float>(i);j++)
	//	{
	//		cout<<".";
	//	}
	//	cout<<endl;
	}

	imshow("hist",histImg);
	waitKey(5);
	
	 
}
//@test
void Histogram::detectEdge(void)
{
	

	Mat I = imread("C:/Users/domenico/Pictures/car_opencv.jpg");
	Mat closed,opened,c2,gradient,edges,I0;
	cvtColor(I,I0,CV_BGR2GRAY);

	

	Mat kernel(3,3,CV_8U,Scalar(1));

	morphologyEx(I0,closed,cv::MORPH_CLOSE,kernel);
	morphologyEx(I0,opened,cv::MORPH_OPEN,kernel);

	imshow("Original",I0);
	imshow("Close",closed);
	imshow("Open",opened);

	morphologyEx(closed,c2,cv::MORPH_OPEN,kernel);
	imshow("Closed+open",c2);
	
	//gradient

	morphologyEx(I0,gradient,cv::MORPH_GRADIENT,kernel);
	imshow("Gradient", gradient);


	//edge
	int soglia = 50; //40 sta sul libro
	threshold(gradient,edges,soglia,255,cv::THRESH_BINARY_INV);
	imshow("edges", edges);

	waitKey(5);

	

}
//@test
void Histogram::detectCorner(void)
{

	Mat Img = imread("C:/Users/domenico/Pictures/car_opencv.jpg");

	Mat I;
	cvtColor(Img,I,CV_BGR2GRAY);




	



	Mat square (5,5,CV_8U,Scalar(1));
	Mat diamond (5,5,CV_8U,Scalar(1));
	Mat croce (5,5,CV_8U,Scalar(0));
	Mat x_shape (5,5,CV_8U,Scalar(0));

	//diamond
   diamond.at<uchar>(0,0)= 0;
   diamond.at<uchar>(0,1)= 0;
   diamond.at<uchar>(1,0)= 0;
   diamond.at<uchar>(4,4)= 0;
   diamond.at<uchar>(3,4)= 0;
   diamond.at<uchar>(4,3)= 0;
   diamond.at<uchar>(4,0)= 0;
   diamond.at<uchar>(4,1)= 0;
   diamond.at<uchar>(3,0)= 0;
   diamond.at<uchar>(0,4)= 0;
   diamond.at<uchar>(0,3)= 0;
   diamond.at<uchar>(1,4)= 0;

   //croce
   for(int i = 0;i<5;i++)
   {
	   croce.at<uchar>(2,i)=1;
	   croce.at<uchar>(i,2)=1;
   }

   //x_shape
   for(int i = 0;i<5;i++)
   {
	   croce.at<uchar>(i,i)=1;
	   croce.at<uchar>(4-i,i)=1;
   }



   Mat I0,I1,result;

  
   dilate(I,I0,croce); //dilate con croce
   erode(I0,I0,diamond); //erode con diamond

   //vs.

   dilate(I,I1,x_shape); //dilate con x_shape
   erode(I1,I1,square); //erode con square

   absdiff(I0,I1,result);  //faccio la differenza assoluta



   imshow("original",I);
   imshow("I0",I0);
   imshow("I1",I1);
   imshow("AbsDiff",result);

   

	//applico le soglie
   int soglia = 40;
   threshold(result,result,soglia,255,THRESH_BINARY);

   


   	//test stampa
	Mat_<uchar>::const_iterator it = result.begin<uchar>();
	Mat_<uchar>::const_iterator itend = result.end<uchar>();
   for(int i=0;it!=itend;++it,++i)
	{
		cout<<int(*it)<<endl;
		if(!*it)
		{
			 
			//cout<<"non null i:"<<i<<" "<<i%result.step<<endl;
		}
		
	}


   imshow("Corner", I0);



}
